package network.server.handler.StoreHandler;

import common.model.Entity.StoreEntity.Category;
import module.StoreService.CategoryService;
import module.StoreService.Impl.CategoryServiceImpl;
import network.protocol.Request;
import network.protocol.Response;
import network.server.RequestHandler;

import java.util.Map;
import java.util.Optional;

/**
 * {@code CategoryHandler} 是分类相关请求的处理器，实现了 {@link RequestHandler} 接口。
 * <p>
 * 主要功能：
 * <ul>
 *     <li>接收客户端请求并解析 action</li>
 *     <li>根据请求的操作类型调用 {@link CategoryService} 对应方法</li>
 *     <li>返回统一封装的 {@link Response} 结果</li>
 * </ul>
 * <p>
 * 支持的操作：
 * <ul>
 *     <li>{@code getCategoryById} - 根据分类 ID 获取分类</li>
 *     <li>{@code getCategoriesByName} - 根据分类名获取分类</li>
 *     <li>{@code getAllCategories} - 获取所有分类</li>
 *     <li>{@code getCategoriesByParentId} - 根据父分类 ID 获取子分类</li>
 *     <li>{@code createCategory} - 创建新分类</li>
 *     <li>{@code updateCategory} - 更新分类信息</li>
 *     <li>{@code deleteCategory} - 删除分类</li>
 *     <li>{@code getCategoryCount} - 获取分类总数</li>
 *     <li>{@code categoryExists} - 检查分类是否存在</li>
 *     <li>{@code categoryNameExists} - 检查分类名是否存在</li>
 *     <li>{@code hasChildCategories} - 检查分类是否有子分类</li>
 * </ul>
 */
public class CategoryHandler implements RequestHandler {
    private final CategoryService categoryService;

    /**
     * 构造函数，初始化时使用 {@link CategoryServiceImpl#getInstance()} 获取单例服务对象。
     */
    public CategoryHandler() {
        this.categoryService = CategoryServiceImpl.getInstance();
    }

    /**
     * 处理来自客户端的请求，根据 {@code action} 调用对应的处理方法。
     *
     * @param req 客户端请求，包含 action 和参数
     * @return 统一的响应对象，包含执行结果或错误信息
     */
    @Override
    public Response<?> handle(Request req) {
        String action = req.getAction();
        String methodName = action.substring(action.indexOf('.') + 1);
        Map<String, Object> params = req.getParams();

        try {
            switch (methodName) {
                case "getCategoryById":
                    return handleGetCategoryById(params);
                case "getCategoriesByName":
                    return handleGetCategoriesByName(params);
                case "getAllCategories":
                    return categoryService.getAllCategories();
                case "getCategoriesByParentId":
                    return handleGetCategoriesByParentId(params);
                case "createCategory":
                    return handleCreateCategory(params);
                case "updateCategory":
                    return handleUpdateCategory(params);
                case "deleteCategory":
                    return handleDeleteCategory(params);
                case "getCategoryCount":
                    return categoryService.getCategoryCount();
                case "categoryExists":
                    return handleCategoryExists(params);
                case "categoryNameExists":
                    return handleCategoryNameExists(params);
                case "hasChildCategories":
                    return handleHasChildCategories(params);
                default:
                    return Response.error("未知操作: " + methodName);
            }
        } catch (NumberFormatException e) {
            return Response.error("参数格式错误: " + e.getMessage());
        } catch (Exception e) {
            return Response.error("处理请求时发生错误: " + e.getMessage());
        }
    }

    /**
     * 根据分类 ID 获取分类。
     *
     * @param params 请求参数，必须包含 {@code id}
     * @return 分类对象或错误响应
     */
    private Response<?> handleGetCategoryById(Map<String, Object> params) {
        if (!params.containsKey("id")) {
            return Response.error("缺少必要参数: id");
        }
        try {
            Object idObj = params.get("id");
            if (idObj == null) {
                return Response.error("id参数不能为null");
            }
            long id = Long.parseLong(idObj.toString());
            return categoryService.getCategoryById(id);
        } catch (NumberFormatException e) {
            return Response.error("id参数格式错误");
        }
    }

    /**
     * 根据分类名称获取分类。
     *
     * @param params 请求参数，必须包含 {@code name}
     * @return 分类对象或错误响应
     */
    private Response<?> handleGetCategoriesByName(Map<String, Object> params) {
        if (!params.containsKey("name")) {
            return Response.error("缺少必要参数: name");
        }
        Object nameObj = params.get("name");
        if (nameObj == null) {
            return Response.error("name参数不能为null");
        }
        String name = nameObj.toString();
        return categoryService.getCategoriesByName(name);
    }

    /**
     * 根据父分类 ID 获取子分类。
     *
     * @param params 请求参数，必须包含 {@code parentId}
     * @return 子分类列表或错误响应
     */
    private Response<?> handleGetCategoriesByParentId(Map<String, Object> params) {
        if (!params.containsKey("parentId")) {
            return Response.error("缺少必要参数: parentId");
        }
        try {
            Object parentIdObj = params.get("parentId");
            if (parentIdObj == null) {
                return Response.error("parentId参数不能为null");
            }
            long parentId = Long.parseLong(parentIdObj.toString());
            return categoryService.getCategoriesByParentId(parentId);
        } catch (NumberFormatException e) {
            return Response.error("parentId参数格式错误");
        }
    }

    /**
     * 创建新分类。
     *
     * @param params 请求参数，必须包含 {@code name}，可选 {@code parentId}
     * @return 创建结果，成功返回 {@code true}，否则返回错误信息
     */
    private Response<?> handleCreateCategory(Map<String, Object> params) {
        if (!params.containsKey("name")) {
            return Response.error("缺少必要参数: name");
        }
        try {
            Category category = new Category();

            Object nameObj = params.get("name");
            if (nameObj == null) {
                return Response.error("name参数不能为null");
            }
            category.setName(nameObj.toString());

            if (params.containsKey("parentId")) {
                Object parentIdObj = params.get("parentId");
                if (parentIdObj != null) {
                    long parentId = Long.parseLong(parentIdObj.toString());
                    category.setParentId(parentId);
                }
            }
            return categoryService.createCategory(category);
        } catch (NumberFormatException e) {
            return Response.error("parentId参数格式错误");
        }
    }

    /**
     * 更新分类信息。
     *
     * @param params 请求参数，必须包含 {@code id}，可选 {@code name}, {@code parentId}
     * @return 更新结果，成功返回 {@code true}，否则返回错误信息
     */
    private Response<?> handleUpdateCategory(Map<String, Object> params) {
        if (!params.containsKey("id")) {
            return Response.error("缺少必要参数: id");
        }
        try {
            Object idObj = params.get("id");
            if (idObj == null) {
                return Response.error("id参数不能为null");
            }
            long id = Long.parseLong(idObj.toString());

            Response<Optional<Category>> response = categoryService.getCategoryById(id);
            if (!response.isSuccess() || response.getData().isEmpty()) {
                return Response.error("未找到指定分类");
            }
            Category category = response.getData().get();

            if (params.containsKey("name")) {
                Object nameObj = params.get("name");
                if (nameObj != null) {
                    category.setName(nameObj.toString());
                }
            }
            if (params.containsKey("parentId")) {
                Object parentIdObj = params.get("parentId");
                if (parentIdObj != null) {
                    long parentId = Long.parseLong(parentIdObj.toString());
                    category.setParentId(parentId);
                }
            }
            return categoryService.updateCategory(category);
        } catch (NumberFormatException e) {
            return Response.error("参数格式错误");
        }
    }

    /**
     * 删除分类。
     *
     * @param params 请求参数，必须包含 {@code id}
     * @return 删除结果，成功返回 {@code true}，否则返回错误信息
     */
    private Response<?> handleDeleteCategory(Map<String, Object> params) {
        if (!params.containsKey("id")) {
            return Response.error("缺少必要参数: id");
        }
        try {
            Object idObj = params.get("id");
            if (idObj == null) {
                return Response.error("id参数不能为null");
            }
            long id = Long.parseLong(idObj.toString());
            return categoryService.deleteCategory(id);
        } catch (NumberFormatException e) {
            return Response.error("id参数格式错误");
        }
    }

    /**
     * 检查分类是否存在。
     *
     * @param params 请求参数，必须包含 {@code id}
     * @return 是否存在，返回 {@code true} 或 {@code false}
     */
    private Response<?> handleCategoryExists(Map<String, Object> params) {
        if (!params.containsKey("id")) {
            return Response.error("缺少必要参数: id");
        }
        try {
            Object idObj = params.get("id");
            if (idObj == null) {
                return Response.error("id参数不能为null");
            }
            long id = Long.parseLong(idObj.toString());
            return categoryService.categoryExists(id);
        } catch (NumberFormatException e) {
            return Response.error("id参数格式错误");
        }
    }

    /**
     * 检查分类名称是否存在。
     *
     * @param params 请求参数，必须包含 {@code name}
     * @return 是否存在，返回 {@code true} 或 {@code false}
     */
    private Response<?> handleCategoryNameExists(Map<String, Object> params) {
        if (!params.containsKey("name")) {
            return Response.error("缺少必要参数: name");
        }
        Object nameObj = params.get("name");
        if (nameObj == null) {
            return Response.error("name参数不能为null");
        }
        String name = nameObj.toString();
        return categoryService.categoryNameExists(name);
    }

    /**
     * 检查某分类是否有子分类。
     *
     * @param params 请求参数，必须包含 {@code parentId}
     * @return 是否有子分类，返回 {@code true} 或 {@code false}
     */
    private Response<?> handleHasChildCategories(Map<String, Object> params) {
        if (!params.containsKey("parentId")) {
            return Response.error("缺少必要参数: parentId");
        }
        try {
            Object parentIdObj = params.get("parentId");
            if (parentIdObj == null) {
                return Response.error("parentId参数不能为null");
            }
            long parentId = Long.parseLong(parentIdObj.toString());
            return categoryService.hasChildCategories(parentId);
        } catch (NumberFormatException e) {
            return Response.error("parentId参数格式错误");
        }
    }
}
